var Compile = function(vm,el,data,option){
    this.$el = this.isElementNode(el) ? el : document.querySelector(el);
    this.$vm = vm;
    this.$data = data;
    this.$method = option.methods;
    
    if(this.$el){
        this.$fragement = this.fragement(this.$el);
        this.init();
        this.$el.appendChild(this.$fragement);
    }
}

Compile.prototype = {
    fragement(el){
        var fragement = document.createDocumentFragment(),children = el.childNodes;
        [].slice.call(children).map(node=>{
            // console.log(node)
            fragement.appendChild(node)
        })
        return fragement;
    },
    init(){
        this.compileInit(this.$fragement);
    },
    compileInit(el){
        var reg = /^\{\{(.*)\}\}$/;
        var childnode = el.childNodes;
        // console.log('content',childnode);
        [].slice.call(childnode).map(node=>{
            // console.log(node)
            if(this.isElementNode(node)){
               
                var attributes = node.attributes;
                
                [].slice.call(attributes).map(attr=>{
                    var name = attr.name,
                        value = attr.value,
                        tagname = node.tagName.toLowerCase();
                       
    
                    if(name.indexOf('v-text')>=0 || name.indexOf('v-bind')>=0 || name.indexOf('v-model')>=0){
                        var content = name.slice(name.indexOf('-')+1);

                        if(tagname === 'input'){
                            // node.value = this.$vm.$option[value]
                            compileUtil.Vmodel(this.$vm,node,'input',value);
                        }else{
                            compileUtil[content](this.$vm,value,node,this.$data)
                        }
                    }else if(name.indexOf('v-on') >=0||name.indexOf('@')>=0){
                        // console.log(name)
                        var event = name.indexOf('@') >=0 ? name.slice(name.indexOf('@')+1) : name.slice(name.indexOf(':')+1);
                            // console.log(event)
                        
                            compileUtil.eventUtil(this.$vm,node,event,this.$method[value]);
                        
                    }
                })
            }
                var contents = node.textContent;
                
                if(reg.test(contents.trim())){
                    // console.log(contents)
                    Object.keys(this.$data).map(key=>{
                        // console.log(contents)
                        // console.log(key)
                        if(contents.indexOf(`{{${key}}}`)>=0&&key !== ""){
                            // console.log('key',key)
                            compileUtil.bind(this.$vm,key,'mustural',node,this.$data)
                        }
                    })
                }
            // }else{
            //     var contents = node.textContent;
                
            //     if(reg.test(contents.trim())){
            //         console.log(contents)
            //         Object.keys(this.$data).map(key=>{
            //             if(key !== "")
            //                 compileUtil.bind(this.$vm,key,'mustural',node,this.$data)
            //         })
            //     }
            // }
        })
    },
    isElementNode(el){
        return el.nodeType === 1;
    }
}

var compileUtil = {
    text(vm,exp,node,data){
        this.bind(vm,exp,'text',node,data)
    },
    bind(vm,exp,type,node,data){
        updateFn[type](vm,node,data[exp],exp)
        new Watcher(vm,exp,function(value,oldValue){
            updateFn&&updateFn[type](vm,node,value,exp,type);
        },data)
    },
    model(vm,exp,node,data){
        this.bind(vm,exp,'model',node,data)
    },
    eventUtil(vm,node,event,fn){
        node.addEventListener(event,fn.bind(vm.$option),false);
    },
    Vmodel(vm,node,event,key){
        // console.log(vm.$option)
        // console.log(key)
        setTimeout(() => {
            node.value = vm.$option[key];
        }, 0);
       node.addEventListener(event,function(e){
        // console.log(node.value)
            vm.$option[key] = e.target.value
            // console.log(vm.$option)
       },false)
    }
}

var updateFn = {
    oldvalue:{},
    text(vm,node,value,key){
        node.innerHTML = value;
    },
    // model(vm,node,value,key){
    //     console.log(key)
    //     console.log(vm)
    //     console.log(value)
    //     node.value = value;
    //     vm.$option[key] = value
    // },
    mustural(vm,node,value,key,type){
        if(type){
            node.textContent = node.textContent.replace(this.oldvalue[key],value)
        }else{
            this.oldvalue[key]=value
            node.textContent = node.textContent.replace(new RegExp(`\{\{${key}\}\}`),value)
        }
    },
    eventHandle(){

    }
}

var regrule = {
    before:/^(.*)\{\{$/ig,
    middle:/\}\}(.*)\{\{/ig,
    after:/\}\}(.*)/ig
}

var valuehandle = {
    _getVal(vm,exp){
        var exp = exp.split('.'),
        me = vm.$option;

        exp.map((value,i)=>{
            me = me[exp]
        })

        return me;
    },
    _setVal(vm,exp,value){
        var exp = exp.split('.'),
            me = vm.$option;

        exp.map((value,i)=>{
            if(i<exp.length-1){
                me = me[exp]
            }else{
                me[exp] = value
            }
        })
    }
}